import { CreepAbilityHelper } from "utils/creep/CreepAbilityHelper"
import { CreepBoostSetup } from "utils/creep/CreepBoostSetup";
import { BodyUtils } from "utils/creep/bodyutils";

export class BattleStrategy
{
    /**
     * 根据敌方的战斗信息和友方的房间能量上限。计算出爬的配置
     * @param stats 
     * @param enegycap 
     * @returns 
     */
    public createCreepBodyConfig(stats:IEnemyTeamSats,enegycap:number,maxboost:number=3)
    {
        for(let i=0;i<=maxboost;i++)
        {
            // rangeattack
            if(enegycap>600)
            {
                const bodys = this.createRangeAttackBodyparts(stats,i as BoostLevel);
                const bodyparts = BodyUtils.calBodyPartsConfig(bodys,enegycap);
                if(bodyparts[1]<=4 || (maxboost==0 && stats.heal==0) )
                {
                    const bodyconfig =  BodyUtils.calRoleConfig(bodys,bodyparts[1]);
                    if(bodyconfig)
                    {
                        return bodyconfig.map(e=>
                            {
                                const newbody = BodyUtils.adaptiveBodys(BodyUtils.flatBodyParts(e[0].body),enegycap);
                                const bodyconfig = BodyUtils.classifyBodyParts(newbody);
                                const thisbodys:[BodyPartConstant,number][]=[];
                                for(let k in bodyconfig)
                                {
                                    thisbodys.push([k as BodyPartConstant,bodyconfig[k as BodyPartConstant] as number ])
                                }
                                e[0].body = BodyUtils.recombineBody(thisbodys,bodyparts[1]>1&&i>0?false:true)
                                e[0].boost = i;
                                return e;
                            });
                    }
                    
                }
            }
        

            // attack.
            {
                let attackbodys = this.createAttackBodyparts(stats,i as BoostLevel);
                if(  attackbodys[ATTACK]<attackbodys[MOVE])
                {
                    attackbodys = this.createAttackBodyparts2(stats,i as BoostLevel);
                }
                const attackbodyparts = BodyUtils.calBodyPartsConfig(attackbodys,enegycap);
                if(attackbodyparts[1]<=4)
                {
                    // 当数量大于1时。就要变成小队了
                    const bodyconfig =  BodyUtils.calRoleConfig(attackbodys,attackbodyparts[1]);
                    if(bodyconfig)
                    {
                        return  bodyconfig.map(e=>
                            {
                                const newbody = BodyUtils.adaptiveBodys(BodyUtils.flatBodyParts(e[0].body),enegycap);
                                const bodyconfig = BodyUtils.classifyBodyParts(newbody);
                                const thisbodys:[BodyPartConstant,number][]=[];
                                for(let k in bodyconfig)
                                {
                                    thisbodys.push([k as BodyPartConstant,bodyconfig[k as BodyPartConstant] as number ])
                                }
                                e[0].body = BodyUtils.recombineBody(thisbodys,attackbodyparts[1]>1?false:true)
                                e[0].boost = i;
                                return e;
                            });
                    }
                   
                }
            }
        }
        return undefined
    }

    /**
     * 计算以蓝球应对，creep的body配置
     * @param stats 
     * @param boost 等级 0-3
     */
    private createRangeAttackBodyparts(stats:IEnemyTeamSats,boost:BoostLevel)
    {
        let brokenDamage =  _.min(_.map(stats.hostileCreeps,e=>CreepAbilityHelper.GetBrokenToughDamage(e,stats.heal)));
        // 伤害要高于他的1.5
        let m_rangeattack:MineralBoostConstant|undefined,m_heal:MineralBoostConstant|undefined,m_tough:MineralBoostConstant|undefined
        if(boost)
        {
            m_rangeattack = CreepBoostSetup.BoostConstant(RANGED_ATTACK,"rangedAttack",boost);
            m_heal = CreepBoostSetup.BoostConstant(HEAL,"heal",boost);
            m_tough= CreepBoostSetup.BoostConstant(TOUGH,"damage",boost);
        }
        if(brokenDamage ==0)
        {
            // 对方没有带治疗的情况,那我就带和他一样的攻击力
            brokenDamage=stats.rangeAttack || stats.attack/3;
        }
        const mydamage = brokenDamage*1.5;
        const mybodys = CreepAbilityHelper.GetMinBodyForDamage(stats.rangeAttack*1.3,m_heal,m_tough);
        const attackcount = CreepAbilityHelper.GetMinBodyForDamageOfRangeAttack(mydamage,m_rangeattack);
        mybodys[RANGED_ATTACK]=attackcount;
        const movecount = BodyUtils.getMoveBodypartNumber(mybodys as any,boost);
        mybodys[MOVE] = movecount;
        return mybodys;
    }

        
    /**
     * 计算以红球应对，creep的body配置,红球以换伤为主
     * @param stats 
     * @param boost 等级 0-3
     */
    private createAttackBodyparts(stats:IEnemyTeamSats,boost:BoostLevel)
    {
        let brokenDamage =  _.min(_.map(stats.hostileCreeps,e=>CreepAbilityHelper.GetBrokenToughDamage(e,stats.heal)));
        // 伤害要高于他的1.5
        let m_attack:MineralBoostConstant|undefined,m_heal:MineralBoostConstant|undefined,m_tough:MineralBoostConstant|undefined
        if(boost)
        {
            m_attack = CreepBoostSetup.BoostConstant(ATTACK,"attack",boost);
            m_heal = CreepBoostSetup.BoostConstant(HEAL,"heal",boost);
            m_tough= CreepBoostSetup.BoostConstant(TOUGH,"damage",boost);
        }
        if(brokenDamage ==0)
        {
            // 对方没有带治疗的情况,那我就带和他一样的攻击力
            brokenDamage=stats.attack|| stats.rangeAttack;
        }
        const mydamage = brokenDamage*1.5;
        const mybodys = CreepAbilityHelper.GetMinBodyForDamage(stats.rangeAttack*1.3,m_heal,m_tough);
        const attackcount = CreepAbilityHelper.GetMinBodyForDamageOfAttack(mydamage,m_attack);
       
        mybodys[ATTACK]=attackcount
        const movecount = BodyUtils.getMoveBodypartNumber(mybodys as any,boost)
        mybodys[MOVE] = movecount;
        return mybodys;
    }
 /**
     * 计算以红球应对，creep的body配置,红球以换伤为主
     * @param stats 
     * @param boost 等级 0-3
     */
    private createAttackBodyparts2(stats:IEnemyTeamSats,boost:BoostLevel)
    {
        let brokenDamage =  _.min(_.map(stats.hostileCreeps,e=>CreepAbilityHelper.GetBrokenToughDamage(e,stats.heal)));
        // 伤害要高于他的1.5
        let m_attack:MineralBoostConstant|undefined,m_heal:MineralBoostConstant|undefined,m_tough:MineralBoostConstant|undefined
        if(boost)
        {
            m_attack = CreepBoostSetup.BoostConstant(ATTACK,"attack",boost);
            m_heal = CreepBoostSetup.BoostConstant(HEAL,"heal",boost);
            m_tough= CreepBoostSetup.BoostConstant(TOUGH,"damage",boost);
        }

        const mydamage = stats.attack+ stats.rangeAttack*3;
        const mybodys = CreepAbilityHelper.GetMinBodyForDamage(stats.heal,m_heal,m_tough);
        const attackcount = CreepAbilityHelper.GetMinBodyForDamageOfAttack(mydamage,m_attack);
        
        mybodys[ATTACK]=attackcount
        const movecount = BodyUtils.getMoveBodypartNumber(mybodys as any,boost)
        mybodys[MOVE] = movecount;
        return mybodys;
    }
}